/*******************************************************************************
 * @(#)CrashExceptionHandler.java 2015年7月2日
 *
 * Copyright 2015 emrubik Group Ltd. All rights reserved.
 * EMRubik PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 *******************************************************************************/
package com.inossem.utils.crashException;

import android.content.Context;
import android.os.Looper;

import com.inossem.utils.base.Utils;
import com.inossem.utils.log.LogUtils;

import java.lang.Thread.UncaughtExceptionHandler;

public class CrashExceptionHandler implements UncaughtExceptionHandler {

    private StringBuffer sb = new StringBuffer();// 保存异常信息

    private UncaughtExceptionHandler uncaughtExceptionHandler;

    private static CrashExceptionHandler carshExceptionHandler;

    private CrashExceptionUtils.CrashExceptionResponse mCrashExceptionResponse;

    private CrashExceptionHandler() {
    }

    private Context mContext;

    /**
     * 获取CrashExceptionHandler对象
     * @author leij
     * @return CrashExceptionHandler对象
     */
    public static synchronized CrashExceptionHandler getInstance() {
        if (carshExceptionHandler == null) {
            carshExceptionHandler = new CrashExceptionHandler();
        }
        return carshExceptionHandler;
    }

    /**
     * 初始化
     * @author leij
     * @param context 上下文
     * @param crashExceptionResponse 捕获异常响应监听
     */
    public void init(Context context, CrashExceptionUtils.CrashExceptionResponse crashExceptionResponse) {
        // 获取默认异常捕获
        uncaughtExceptionHandler = Thread.getDefaultUncaughtExceptionHandler();
        Thread.setDefaultUncaughtExceptionHandler(this);
        this.mContext = context;
        this.mCrashExceptionResponse = crashExceptionResponse;
    }

    /**
     * 未捕获的异常
     * @author leij
     * @param thread 线程对象
     * @param ex 异常对象
     */
    @Override
    public void uncaughtException(Thread thread, Throwable ex) {
        try {
            // 处理捕获的异常
            crashException(mContext, ex);
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
            uncaughtExceptionHandler.uncaughtException(thread, ex);
        }
        // 回调函数
        new Thread() {
            @Override
            public void run() {
                Looper.prepare();
                mCrashExceptionResponse.onResponse(mContext);
                Looper.loop();
            }
        }.start();
    }

    /**
     * 捕获异常
     * @author leij
     * @param context 上下文
     * @param ex 异常对象
     */
    private void crashException(Context context, Throwable ex) {
        // 获取APP版本，查询设备基本信息，获取崩溃信息，保存文件
        collectCrashInfo(context, ex);
        LogUtils.logCatchExceptionE(context,sb.toString(),null);
    }

    /**
     * 收集异常信息
     * @author leij
     * @param context 上下文
     * @param ex 异常对象
     */
    private void collectCrashInfo(Context context, Throwable ex) {
        // 正常打印异常
        ex.printStackTrace();
        sb.append(Utils.exceptionToString(ex));

    }

}
